package com.ifast.asset.controller;


import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;

import com.alibaba.druid.sql.ast.statement.SQLIfStatement;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.ServiceException;
import com.ifast.asset.dao.AssetsDao;
import com.ifast.asset.domain.Assets;
import com.ifast.asset.domain.TaskrecordDO;
import com.ifast.asset.quartz.StartOfDayJob;
import com.ifast.asset.quartz.service.JobService;
import com.ifast.asset.service.TaskrecordService;
import com.ifast.asset.util.HttpUtil;
import com.ifast.asset.util.NewThreadPool;
import com.ifast.asset.util.NmapExecuteUtil;
import io.swagger.annotations.ApiOperation;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.*;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.ifast.common.annotation.Log;
import com.ifast.common.base.BaseController;
import com.ifast.common.utils.Result;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * <pre>
 *
 * </pre>
 * <small> 2021-03-02 17:43:23 | Aron</small>
 */
@Controller
@RequestMapping("/wxmp/taskrecord")
public class TaskrecordController extends BaseController {
    @Autowired
    private TaskrecordService taskrecordService;
    @Autowired
    private JobService jobService;
    @Value("${checkUrl}")
    String checkUrl;
    @Resource
    private NmapExecuteUtil nmapExecuteUtil;
    @Resource
    private AssetsDao assetsDao;


    @GetMapping()
        //@RequiresPermissions("wxmp:taskrecord:taskrecord")
    String Taskrecord() {
        return "wxmp/taskrecord/taskrecord";
    }

    @ResponseBody
    @GetMapping("/list")
    //@RequiresPermissions("wxmp:taskrecord:taskrecord")
    Result<Page<TaskrecordDO>> list(TaskrecordDO taskrecordDTO, int pageNum, int pageSize) {
        Wrapper<TaskrecordDO> wrapper = new EntityWrapper<>(taskrecordDTO).orderBy("id", false);
        Page<TaskrecordDO> page = taskrecordService.selectPage(getPage(TaskrecordDO.class, pageNum, pageSize), wrapper);
        return Result.ok(page);
    }

    @GetMapping("/add")
        //@RequiresPermissions("wxmp:taskrecord:add")
    String add() {
        return "wxmp/taskrecord/add";
    }

    @GetMapping("/edit/{id}")
        //@RequiresPermissions("wxmp:taskrecord:edit")
    String edit(@PathVariable("id") Integer id, Model model) {
        TaskrecordDO taskrecord = taskrecordService.selectById(id);
        model.addAttribute("taskrecord", taskrecord);
        return "wxmp/taskrecord/edit";
    }

    @ResponseBody
    @Log("添加资产识别任务")
    @RequestMapping("/save")
    @ApiOperation("添加资产识别任务")
    //@RequiresPermissions("wxmp:taskrecord:add")
    public Result<Object> save(@RequestBody TaskrecordDO record) {

        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        record.setTime(simpleDateFormat.format(date));
        taskrecordService.insert(record);
        if (record.getType().equals("0")) {
            //根据组ip查询 资产
            if (record.getGroupId() != null && !"".equals(record.getGroupId())) {
                //解析资产组执行
                List<Assets> assets = assetsDao.saveByGroup(record.getGroupId());
                for (int i = 0; i < assets.size(); i++) {
                    record.setIp(assets.get(i).getIp());
                    nmapExecuteUtil.execute(record);
                }
            } else {
                //单次执行
                record.setIp(record.getIp());
                nmapExecuteUtil.execute(record);
            }

        } else if (record.getType().equals("1")) {

            //新的添加定时扫描
            jobService.addJob(record.getTaskName(), "testuser", StartOfDayJob.class, record.getCron(), JSON.toJSONString(record));
        }
        return Result.ok();
    }

    @ResponseBody
    @PostMapping("/saveByExcle")
    //@RequiresPermissions("wxmp:taskrecord:add")
    public Result<Object> saveByExcle(@RequestParam(name = "file") MultipartFile file, @RequestParam(name = "taskName", required = false) String taskName) {

        TaskrecordDO record = new TaskrecordDO();
        record.setTaskName(taskName);

        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        record.setTime(simpleDateFormat.format(date));
        record.setType("0");
        taskrecordService.insert(record);
        try {
            FileInputStream fileInputStream = null;
            fileInputStream = (FileInputStream) file.getInputStream();

            XSSFWorkbook sheets = new XSSFWorkbook(fileInputStream);
            //获取sheet
            XSSFSheet sheet = sheets.getSheetAt(0);
            MusicImplements musicImplements = new MusicImplements(nmapExecuteUtil,sheet,record);
            ExecutorService executorService = NewThreadPool.getExecutorService();
            executorService.submit(musicImplements);

        } catch (Exception e) {

        }
        return Result.ok();
    }
    @ResponseBody
    @GetMapping("/downLoadExcle")
    public Result<Object> downLoadExcle(HttpServletRequest request , HttpServletResponse response){

        // 1: 找到excel文件
        String storePath =  ClassUtils.getDefaultClassLoader().getResource("").getPath();
        String fileName = "record.xlsx";

        File file = new File(storePath + fileName);
        if (!file.exists()) {
            throw new RuntimeException("file do not exist");
        }
        InputStream inputStream = null;
        ServletOutputStream servletOutputStream = null;
        // 重置response
        response.reset();
        //设置http头信息的内容
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/vnd.ms-excel");
        response.addHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
        int fileLength = (int) file.length();
        response.setContentLength(fileLength);

        try {
            if (fileLength != 0) {
                inputStream = new FileInputStream(file);
                byte[] buf = new byte[4096];
                // 创建输出流
                servletOutputStream = response.getOutputStream();
                int readLength;
                // 读取文件内容并输出到response的输出流中
                while ((readLength = inputStream.read(buf)) != -1) {
                    servletOutputStream.write(buf, 0, readLength);
                }
            }
        } catch (IOException e) {
            throw new RuntimeException("download file error");
        } finally {
            try {
                // 关闭ServletOutputStream
                if (servletOutputStream != null) {
                    servletOutputStream.flush();
                    servletOutputStream.close();
                }
                // 关闭InputStream
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return Result.ok();
    }

    @Log("修改")
    @ResponseBody
    @RequestMapping("/update")
    //@RequiresPermissions("wxmp:taskrecord:edit")
    public Result<String> update(@RequestBody TaskrecordDO taskrecord) {
        boolean update = taskrecordService.updateById(taskrecord);
        return update ? Result.ok() : Result.fail();
    }

    @Log("删除")
    @PostMapping("/remove")
    @ResponseBody
    //@RequiresPermissions("wxmp:taskrecord:remove")
    public Result<String> remove(Integer id) {
        taskrecordService.deleteById(id);
        return Result.ok();
    }

    @Log("批量删除资产试别任务")
    @PostMapping("/batchRemove")
    @ResponseBody
    //@RequiresPermissions("wxmp:taskrecord:batchRemove")
    public Result<String> remove(@RequestBody Integer[] ids) {
        //判断如果时定时任务则删除定时任务
        for (int i = 0; i < ids.length; i++) {

            TaskrecordDO taskrecord = taskrecordService.selectById(ids[i]);
            if ("1".equals(taskrecord.getType())) {
                jobService.deleteJob(taskrecord.getTaskName(), "testuser");
            }
        }
        taskrecordService.deleteBatchIds(Arrays.asList(ids));
        return Result.ok();
    }

    public void nMapRequest(String url) {
        try {
            CloseableHttpClient client = null;
            CloseableHttpResponse response = null;
            try {
                HttpGet httpGet = new HttpGet(url);

                client = HttpClients.createDefault();
                response = client.execute(httpGet);
                HttpEntity entity = response.getEntity();
                String result = EntityUtils.toString(entity);
                System.out.println(result);
            } finally {
                if (response != null) {
                    response.close();
                }
                if (client != null) {
                    client.close();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
class MusicImplements implements Runnable {

    NmapExecuteUtil nmapExecuteUtil;
    XSSFSheet sheet;
    TaskrecordDO record;
    public MusicImplements(NmapExecuteUtil nmapExecuteUtil,XSSFSheet sheet,TaskrecordDO record){

        this.nmapExecuteUtil = nmapExecuteUtil;
        this.sheet = sheet;
        this.record = record;
    }

    @Override
    public void run() {

        boolean flag = false;
        for (int i = 0; i < sheet.getPhysicalNumberOfRows(); i++) {
            XSSFRow row = sheet.getRow(i);
            try {
                if (i==0&&"ip/域名".equals(row.getCell(0).toString())) {

                    flag = true;
                    continue;
                }
                if (!flag) {

                    continue;
                }
                record.setIp(row.getCell(0).toString());
            } catch (Exception e) {
            }
            nmapExecuteUtil.execute(record);
        }
    }
}
